package com.yiyuan.app.service.impl;

import com.guaike.core.entity.result.Result;
import com.guaike.core.redis.context.ApiContext;
import com.guaike.core.utils.CompareUtil;
import com.guaike.core.utils.LocalDateUtil;
import com.yiyuan.app.dao.MRankPinecutDailyDAO;
import com.yiyuan.app.dao.MRankPinecutWeekDAO;
import com.yiyuan.app.dao.UAppUserDAO;
import com.yiyuan.app.dao.UAppUserEquityDAO;
import com.yiyuan.app.entity.enums.RankSearchTypeEnum;
import com.yiyuan.app.entity.po.MRankPinecutDailyPO;
import com.yiyuan.app.entity.po.MRankPinecutWeekPO;
import com.yiyuan.app.entity.po.UAppUserEquityPO;
import com.yiyuan.app.entity.po.UAppUserPO;
import com.yiyuan.app.entity.result.AppUser;
import com.yiyuan.app.entity.result.BaseRankVO;
import com.yiyuan.app.entity.result.RankVO;
import com.yiyuan.app.service.MRankPinecutService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Objects;

/**
 * @Author: zhangxilin
 * @Date: 2025/3/17
 */
@Slf4j
@Service
public class MRankPinecutServiceImpl implements MRankPinecutService {

    @Autowired
    private UAppUserDAO uAppUserDAO;
    @Autowired
    private UAppUserEquityDAO uAppUserEquityDAO;
    @Autowired
    private MRankPinecutDailyDAO mRankPinecutDailyDAO;
    @Autowired
    private MRankPinecutWeekDAO mRankPinecutWeekDAO;

    @Override
    public Result<RankVO> pinecutRankList(String rankType) {

        if (Objects.isNull(RankSearchTypeEnum.getByCode(rankType))) {
            return Result.failure().message("非法的榜单搜索类型").build();
        }
        AppUser currentUser = ApiContext.getCurrentUser();
        UAppUserPO myPO = uAppUserDAO.findById(currentUser.getUserId());
        UAppUserEquityPO myEquityPO = uAppUserEquityDAO.findOne(UAppUserEquityPO::getUserId, currentUser.getUserId());
        RankVO vo = new RankVO();
        vo.setNickName(myPO.getNickname());
        vo.setAvatarurl(myPO.getAvatarurl());
        vo.setVipGrade(myEquityPO.getVipGrade());
        if(CompareUtil.isEqual(RankSearchTypeEnum.DAILY.getCode(),rankType)){
            return getPinecutDailyRankList(vo, currentUser,myEquityPO);
        }else if(CompareUtil.isEqual(RankSearchTypeEnum.WEEK.getCode(),rankType)){
            return getPinecutWeekRankList(vo, currentUser,myEquityPO);
        }else if(CompareUtil.isEqual(RankSearchTypeEnum.PRE_DAILY.getCode(),rankType)){
            return getPinecutPreweekRankList(vo, currentUser);
        }
        return Result.success().data(vo).build();
    }

    private Result<RankVO> getPinecutDailyRankList(RankVO vo,AppUser currentUser,UAppUserEquityPO myEquityPO){
        LocalDate now = LocalDate.now();
        List<MRankPinecutDailyPO> dailyPOList =  mRankPinecutDailyDAO.findList(MRankPinecutDailyPO::getStartDate, now, MRankPinecutDailyPO::getRankNo, true);
        List<BaseRankVO> baseRankVOList = Lists.newArrayList();
        for(MRankPinecutDailyPO po: dailyPOList){
            BaseRankVO baseRankVO = new BaseRankVO();
            baseRankVO.setRank(po.getRankNo());
            baseRankVO.setNickName(po.getNickname());
            baseRankVO.setAvatarurl(po.getAvatarurl());
            baseRankVO.setVipGrade(po.getVipGrade());
            baseRankVO.setValue(po.getPinecut()+"");
            baseRankVO.setPrize(po.getPrize());
            if (CompareUtil.isEqual(po.getUserId(), currentUser.getUserId())) {
                vo.setIsRank(Boolean.TRUE);
                vo.setNickName(po.getNickname());
                vo.setAvatarurl(po.getAvatarurl());
                vo.setVipGrade(po.getVipGrade());
                vo.setValue(baseRankVO.getValue());
                vo.setPrize(baseRankVO.getPrize());
                vo.setRank(baseRankVO.getRank());
            }
            baseRankVOList.add(baseRankVO);
        }
        if (!vo.getIsRank()) {
            Integer myPineNut = (myEquityPO == null  || myEquityPO.getPineNut() == null)? 0: myEquityPO.getPineNut();
            Integer lastPineNut = dailyPOList.get(dailyPOList.size()-1).getPinecut();
            lastPineNut = lastPineNut==null? 0 : lastPineNut;
            Integer diff = lastPineNut - myPineNut;
            vo.setDiff(diff+"");
        }
        return Result.success().data(vo).build();
    }
    private Result<RankVO> getPinecutWeekRankList(RankVO vo,AppUser currentUser,UAppUserEquityPO myEquityPO){
        LocalDate now = LocalDate.now();
        LocalDate monday =  now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));

        List<MRankPinecutWeekPO> weekPOList =  mRankPinecutWeekDAO.findList(MRankPinecutWeekPO::getStartDate, monday, MRankPinecutWeekPO::getRankNo, true);
        List<BaseRankVO> baseRankVOList = Lists.newArrayList();
        for(MRankPinecutWeekPO po: weekPOList){
            BaseRankVO baseRankVO = new BaseRankVO();
            baseRankVO.setRank(po.getRankNo());
            baseRankVO.setNickName(po.getNickname());
            baseRankVO.setAvatarurl(po.getAvatarurl());
            baseRankVO.setVipGrade(po.getVipGrade());
            baseRankVO.setValue(po.getPinecut()+"");
            baseRankVO.setPrize(po.getPrize());
            if (CompareUtil.isEqual(po.getUserId(), currentUser.getUserId())) {
                vo.setIsRank(Boolean.TRUE);
                vo.setNickName(po.getNickname());
                vo.setAvatarurl(po.getAvatarurl());
                vo.setVipGrade(po.getVipGrade());
                vo.setValue(baseRankVO.getValue());
                vo.setPrize(baseRankVO.getPrize());
                vo.setRank(baseRankVO.getRank());
            }
            baseRankVOList.add(baseRankVO);
        }
        if (!vo.getIsRank()) {
            Integer myPineNut = (myEquityPO == null  || myEquityPO.getPineNut() == null)? 0: myEquityPO.getPineNut();
            Integer lastPineNut = weekPOList.get(weekPOList.size()-1).getPinecut();
            lastPineNut = lastPineNut==null? 0 : lastPineNut;
            Integer diff = lastPineNut - myPineNut;
            vo.setDiff(diff+"");
        }

        return Result.success().data(vo).build();
    }
    private Result<RankVO> getPinecutPreweekRankList(RankVO vo,AppUser currentUser){

        LocalDate now = LocalDate.now();
        LocalDate monday =  now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDate premonday = monday.minusWeeks(1);

        List<MRankPinecutWeekPO> weekPOList =  mRankPinecutWeekDAO.findList(MRankPinecutWeekPO::getStartDate, premonday, MRankPinecutWeekPO::getRankNo, true);
        List<BaseRankVO> baseRankVOList = Lists.newArrayList();
        for(MRankPinecutWeekPO po: weekPOList){
            BaseRankVO baseRankVO = new BaseRankVO();
            baseRankVO.setRank(po.getRankNo());
            baseRankVO.setNickName(po.getNickname());
            baseRankVO.setAvatarurl(po.getAvatarurl());
            baseRankVO.setVipGrade(po.getVipGrade());
            baseRankVO.setValue(po.getPinecut()+"");
            baseRankVO.setPrize(po.getPrize());
            if (CompareUtil.isEqual(po.getUserId(), currentUser.getUserId())) {
                vo.setIsRank(Boolean.TRUE);
                vo.setNickName(po.getNickname());
                vo.setAvatarurl(po.getAvatarurl());
                vo.setVipGrade(po.getVipGrade());
                vo.setValue(baseRankVO.getValue());
                vo.setPrize(baseRankVO.getPrize());
                vo.setRank(baseRankVO.getRank());
            }
            baseRankVOList.add(baseRankVO);
        }
        return Result.success().data(vo).build();
    }

    public static void main(String[] args) {
        LocalDate now = LocalDate.now();

        LocalDate monday =  now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        LocalDate sunday =  now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        System.out.println("本周星期一的日期是：" + monday);
        System.out.println("本周星期天的日期是：" + sunday);

        System.out.println("上周星期一的日期是：" + monday.minusWeeks(1));
        System.out.println("上周星期天的日期是：" + sunday.minusWeeks(1));
    }
}
